package edu.krazy.engine;

/**
 * @(#)Loader.java
 *
 *
 * @author 
 * @version 1.00 2008/10/22
 */
import java.io.*;
import java.util.StringTokenizer;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;
import javax.media.opengl.*;

public class Loader {

private Texture modelTexture;
private String FileName;
private Model3D currentModel3D;
private boolean hasTexture;
private int coordCount;
private float v1_U,v1_V, v2_U, v2_V, v3_U, v3_V;
    public Loader(String file) {
    hasTexture= false;	
    coordCount = 0;	
    FileName = file;
    readAndParseFile(file);
    modelTexture = null;
    	
    }
    
   public void readAndParseFile(String fileName){
     BufferedReader file;
     	int numLines = 0;
     	String currentLine = "";
     	StringTokenizer st;
		Vertex3f[] vertexList = null; 
		Face[] faceList = null;
     	System.out.println("loading 3D Model: "+fileName);
    	try{
    		file = new BufferedReader(new FileReader(fileName));
    		
    		while(file.readLine()!= null){
    			numLines++;
    			//System.out.println("Leyendo linea "+numLines);
    			  }	  
    		file.close();
    	}catch(IOException e){
    		System.out.println("Can not find 3d file "+e.toString());	
    	}
    	
    
    	try{
    		
    		file = new BufferedReader(new FileReader(fileName));
    		int numVertices = 0;
    		int numFaces = 0;
    		int currentVertex = 0;
    		int currentFace = 0;
    		for(int i=0; i<numLines;i++){
    			
    			currentLine = file.readLine();
    			st = new StringTokenizer(currentLine);
    			while(st.hasMoreTokens()){
    				String currentToken = st.nextToken();
    				
    				if(currentToken.equals("Vertices:"))
    				{
						numVertices = Integer.parseInt(st.nextToken());    				
    					System.out.println("Numero de Vertices: "+numVertices);
    						vertexList = new Vertex3f[numVertices];
    				}
    				
    					if(currentToken.equals("Faces:"))
    				{
						numFaces = Integer.parseInt(st.nextToken());    				
    					System.out.println("Numero de Caras: "+numFaces);
    					faceList = new Face[numFaces];
    				}
    				if(currentToken.equals("vt")){
    					
    					switch(coordCount){
    						
    						case 0:
    							v3_U =Float.parseFloat(st.nextToken());
    							v3_V =1-Float.parseFloat(st.nextToken());
    							coordCount++;
    						break;
    						
    						case 1:
    							v2_U = Float.parseFloat(st.nextToken());
    							v2_V = 1-Float.parseFloat(st.nextToken());
    							coordCount++;
    							break;
    							
    						case 2:	
    							
    							v1_U = Float.parseFloat(st.nextToken());
    							v1_V = 1-Float.parseFloat(st.nextToken());
    							coordCount = 0;
    							
    							break;
    						
    					}
    					
    					break;	
    				}
    				if(currentToken.equals("v")){
    					
    					float x,y,z;
    					x= Float.parseFloat(st.nextToken());
    					y= Float.parseFloat(st.nextToken());
    					z= Float.parseFloat(st.nextToken());
    					
    					
    					Vertex3f vertexTemp = new Vertex3f(x,y,z);	
    					vertexList[currentVertex] =vertexTemp;
    					currentVertex++; 
    					break;   					
    				}
    			
    				if(currentToken.equals("f")){
    					
    					int v1,v2,v3;
    					String tmp = st.nextToken();
    					if(tmp.endsWith("/-1")|tmp.endsWith("/-2")|tmp.endsWith("/-3")){
    						
    						hasTexture= true;
    						int endIndex = tmp.indexOf("/");
    						v1 = Integer.parseInt(tmp.substring(0,endIndex));
    						vertexList[v1-1].setU(v1_U); //asignar coordenadas de texturas
    						vertexList[v1-1].setV(v1_V);
    						//cambio de token
    						tmp = st.nextToken();
    						endIndex = tmp.indexOf("/");
    						v2 = Integer.parseInt(tmp.substring(0,endIndex));
    						vertexList[v2-1].setU(v2_U); //asignar coordenadas de texturas
    						vertexList[v2-1].setV(v2_V);
    						//cambio de token
    						tmp = st.nextToken();
    						endIndex = tmp.indexOf("/");
    						v3 = Integer.parseInt(tmp.substring(0,endIndex));
    						
    						vertexList[v3-1].setU(v3_U); //asignar coordenadas de texturas
    						vertexList[v3-1].setV(v3_V);
	
    					}else{
    						
    						hasTexture = false;
    						v1= Integer.parseInt(tmp);
    						v2= Integer.parseInt(st.nextToken());
    						v3= Integer.parseInt(st.nextToken());
    					
    					}
    					
    					
    					Face faceTemp = new Face(vertexList[v1-1],vertexList[v2-1],vertexList[v3-1]);	
    					faceList[currentFace] =faceTemp;
    					currentFace++; 
    						break;   					
    				}	
    			}
    			//System.out.println(currentLine);
    		}
    		createModel3D(faceList,fileName);
    		
    		file.close();	
    	}catch(IOException e){
    		System.out.println(e.toString());
    	}
    	
    	
    }
    
        

    public Texture loadTexture(String fnm){
    	
    	Texture tex = null;
    	
    	String fileName = fnm.substring(0,fnm.indexOf(".obj"));
    	fileName= fileName+".jpg"; //only jpg textures this time
    	System.out.println("loading texture file "+fileName );
    	BufferedImage im = null;
    	
    	try{
    		im = ImageIO.read( new File(fileName) );  //carga el archivo   
 	    	tex = TextureIO.newTexture( im, false);      //crea la textura de openGL
 	    	
 	    	tex.setTexParameteri(GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);      
 	    	tex.setTexParameteri(GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);  
    		
    		System.out.println("successfully loaded texture");
    	}catch(Exception e){
    		System.out.println("error loading texture "+fileName+"Error "+e.toString());
    	}
    	
    	return tex;
    }
    
     public void createModel3D(Face[] fl,String texName){
     	currentModel3D = new Model3D (fl);
     	if(hasTexture){
     		
     		modelTexture = loadTexture(texName);
     		currentModel3D.setTexture(modelTexture);
     	}
     		
     	else
     		modelTexture = null;
     }
     public Model3D getModel3D(){
     	
     	return currentModel3D;
     }
    	
    
    
}
     
     
